package com.xqpaymall.sso.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.xqpaymall.common.constant.WhiteContant;
import com.xqpaymall.common.domain.vo.base.BaseResponseVo;
import com.xqpaymall.common.enumm.RetEnum;
import com.xqpaymall.common.util.JwtTokenUtils;
import com.xqpaymall.sso.annotation.SkipToken;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.lang.reflect.Method;

/**
 * @ Author     ：marui
 * @ Date       ：Created in 10:52 2019/10/15
 */
@Component
public class AuthInterceptor extends HandlerInterceptorAdapter {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String url = request.getRequestURI();
        PrintWriter out = null;
        // 判断有无SkipToan注解
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        if (canSkipToken(handlerMethod)) {
            return true;
        }
        // 如果在白名单中则直接放行
        for (String whiteUrl : WhiteContant.URL_WHITE_LIST) {
            if (url.equals(whiteUrl)) {
                return true;
            }
        }
        String token = request.getHeader("token");
        if(!StringUtils.isNotEmpty(token)){
            out = response.getWriter();
            BaseResponseVo baseResponseVo = new BaseResponseVo();
            baseResponseVo.setCode(RetEnum.RET_TOKEN_ILLEGAL.getCode());
            baseResponseVo.setMessage(RetEnum.RET_TOKEN_ILLEGAL.getMessage());
            baseResponseVo.setData(null);
            out.print(JSONObject.toJSONString(baseResponseVo));
            return false;
        }
        // 验证token是否有效
        try {
            JwtTokenUtils.phaseToken(token);
            return true;
        } catch (Exception e) {
            // token无效
            out = response.getWriter();
            BaseResponseVo baseResponseVo = new BaseResponseVo();
            baseResponseVo.setCode(RetEnum.RET_TOKEN_ILLEGAL.getCode());
            baseResponseVo.setMessage(RetEnum.RET_TOKEN_ILLEGAL.getMessage());
            baseResponseVo.setData(null);
            out.print(JSONObject.toJSONString(baseResponseVo));
            return false;
        }
    }


    /**
     * 判断类或方法是否有@Skiptoken注解
     *
     * @param handlerMethod
     * @return
     */
    private boolean canSkipToken(HandlerMethod handlerMethod) {
        // 类上是否有@Skiptoken注解
        Class declaringClass = handlerMethod.getMethod().getDeclaringClass();
        if (declaringClass.getAnnotation(SkipToken.class) != null) {
            return true;
        }
        // 方法上是否有@Skiptoken注解
        Method method = handlerMethod.getMethod();
        if (method.getAnnotation(SkipToken.class) != null) {
            return true;
        }
        return false;
    }

}
